const { src, dest, parallel, series, watch } = require('gulp')
const del = require('del');//不是gulp的插件
const browserSync = require('browser-sync');//不是gulp的插件
const bs = browserSync.create()
const loadPlugins = require('gulp-load-plugins');//自动加载所有gulp插件
const plugins = loadPlugins()
const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider1'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}


const style = () => {
  return src('src/assets/styles/*.scss', { base: 'src' })//profixed with '_' scss file which will not be bundled
    .pipe(plugins.sass())
    .pipe(dest('dist'))
}

const script = () => {
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
    .pipe(dest('dist'))
}

const page = () => {
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data, defaults: { cache: false } }))//该插件会缓存html,记得关闭改功能
    .pipe(dest('dist'))
}

const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const font = (done) => {
  src('src/assets/fonts/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
  done()
}

const extra = () => {//处理public下静态资源
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const clean = () => {//清除dist和空文件夹
  return del(['dist']);
}

/**
 * 文件引用处理
 * 该插件会将依赖的文件重新打包成新的文件。放在dist目录下
 */
const useref = () => {
  return src('dist/*html', { base: 'dist' })
    .pipe(plugins.useref({ searchPath: ['dist', '.'] }))//先行dist目录下找，在行项目根目录下找。
    .pipe(dest('dist'))
}

/**
 * 使用不同插件压缩不同类型文件(css,js,html);
 * 由于不同任务是处理不同类型的文件,所以此时需要gulp-if文件类型进行判断。从而执行不同任务
 * 通过gulp-clean-css,gulp-htmlmin,gulp-uglify分别取压缩css,html,js
 */
const cssHtmlJSMin = () => {
  return src('dist/**', { base: 'dist' })
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin(
      {
        collapseWhitespace: true,
        minifyCSS: true,
        minifyJS: true
      }
    )))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(dest('dist'))
}


/* 开启一个开发服务器 */
const serve = () => {//开发服务器肯定是处理加工后的静态资源
  /* 通过gulp的watch方法监听文件的变化，从而执行相应的任务 */
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  watch('src/*.html', page)
  // watch('src/assets/images/**',image)
  // watch('src/assets/fonts/**', font)
  // watch('public/**', extra)
  watch(['src/assets/images/**', 'src/assets/fonts/**', 'public/**'], bs.reload)

  bs.init({
    notify: false,//页面刷新的小提示
    port: 33333,
    files: 'dist/**',//监听dist下的文件变化,同步到浏览器中。也可以通过正在任务后面通过直接调用bs.reload()方法。
    server: {
      // baseDir: 'dist',
      baseDir: ['dist', 'src', 'public'],//资源请求先从 dist-->src-->public目录下找
      routes: {//开发时指定dist文件中‘/node_modules’的请求位置,优先于baseDir。这方式打包后的dist就会有问题
        '/node_modules': 'node_modules'
      }
    }
  })
}


/*基本的HTML,CSS,JS文件的编译任务*/
const compile = parallel(style, script, page)

/* 开启本地服务器的任务 */
const develop = series(compile, serve)

/* 构建任务 */
const build = series(clean, series(parallel(compile, image, font, extra), useref, cssHtmlJSMin))

module.exports = {
  clean,
  build,
  develop
}
